home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
snip9_91.arc
/
RAND3.C
< prev
next >
Wrap
Text File
|
1991-09-17
|
2KB
|
45 lines
/*
This type of random generators originate in early 1950's, and their
good properties were well known by late 50's (cf. D.Knuth 2nd ed.,
vol 2, section 3.2.2). A table of 90 different "magic pairs" like (97,23)
is also given in Knuth, as well as generalizations of the simple add to
primitive polynomials as suggested in your message.
As for practical implementations on a micro, the floating point version
will be very slow compared to integer version (even with 8087). I've
actually used exactly the same pair (97,23) combined with lookup based
CRC-16 instead of an add to obtain very fast and practically unlimited
source for random numbers. One should note that to obtain floating point
sequence, it is not enough to concatenate succesive random numbers from
the say 16-bit integer generator. Instead one should use 32-bit integers
or 64-bit integers for float/double (best done in assembler), with proper
range reduction on the exponent part (usually just an AND/OR mask). As to
seeding of the array[97], one can use rand() coupled with time/date
functions as suggested in several other responses. I've used PC timer
8253 directly which runs at 1.19 Mhz, coupled with date and keyboard
interrupt, the array is re-seeded by adding new-seed-rand() values to
the existent ones whenever a key was struck. Also, the random numbers
are continuously generated in any program-idle state.
The core of the algorithm (without CRC and seed generator) is:
*/
/********************************************************************
Random Array ra[] is initialized to not-all-even, with e.g. rand()
coupled with time/date. Before using the numbers, few thousands
(+/- random number) should be generated and discarded.
********************************************************************/
typedef unsigned int rn;
#define RA_TOP (ra+96)
rn ra[97];
rn *p97=RA_TOP, *p23=ra+22;
rn fast_rnd()
{ rn r;
r = (*p97-- += *p23--);
if (p97 < ra) p97=RA_TOP;
else if (p23 < ra) p23=RA_TOP;
return(r);
}